import app from './app';
import fs from 'fs'
import mongo from './mongo';
import redis from './redis';
import debugTool from 'debug'
import eurecaServer from './eureca.io'
import SocketIO from './socket.io'
import { execute, subscribe } from 'graphql';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import schema from './schema'

const debug = debugTool('server')

const HTTP_PORT = process.env.PORT || 5000
// const host = process.env.HOSTNAME || '0.0.0.0';
const WS_PORT = 5001;
// SSL options
const options = {
  key: fs.readFileSync('./src/ssl/key.pem'),
  cert: fs.readFileSync('./src/ssl/cert.pem')
}

// Launch Node.js server
const server = require('https').createServer(options, app.callback())
SocketIO.attach(server)
eurecaServer.attach(server)

// Create WebSocket listener server
const websocketServer = require('https').createServer(options, (request, response) => {
  response.writeHead(404);
  response.end();
});

// Bind it to port and start listening
websocketServer.listen(WS_PORT, () => console.log(
  `Websocket Server is now running on http://localhost:${WS_PORT}`
));
const subscriptionServer = SubscriptionServer.create(
  {
    schema,
    execute,
    subscribe,
  },
  {
    server: websocketServer,
    path: '/graphql',
  },
);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(HTTP_PORT);
server.on('error', onError);
server.on('listening', onListening);

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  const bind = typeof HTTP_PORT === 'string'
    ? 'Pipe ' + HTTP_PORT
    : 'Port ' + HTTP_PORT;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}
/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  const addr = server.address();
  const bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

// Shutdown Node.js app gracefully
function handleExit(options, err) {
    if (options.cleanup) {
        const actions = [server.close, mongo.close, redis.quit];
      console.log(mongo.close)
        actions.forEach((close, i) => {
            try {
                close(() => { if (i === actions.length - 1) process.exit(); });
            } catch (err) { if (i === actions.length - 1) process.exit(); }
        });
    }
    if (err) console.log(err.stack);
    if (options.exit) process.exit();
}

process.on('exit', handleExit.bind(null, { cleanup: true }));
process.on('SIGINT', handleExit.bind(null, { exit: true }));
process.on('SIGTERM', handleExit.bind(null, { exit: true }));
process.on('uncaughtException', handleExit.bind(null, { exit: true }));
